/*  UTF-8 ENCODED rus  */

/*
 * global_functions.h
 *
 *  Created on: 20.11.2008
 *      Author: Denjs
 */

#ifndef GLOBAL_FUNCTIONS_H_
#define GLOBAL_FUNCTIONS_H_

#include <QApplication>

#include "./bots/t_BaseBot.h"
#include "./bots/t_FileList.h"
#include "./bots/t_TreeWidget.h"
#include "./bots/t_TreeWidgetItem.h"
#include <classes/t_QDLibManager.h>

/*
 //TODO Функция input() - для ввода значений
 //TODO Функция shell() - для выполнения команд оболочки


 */


/*
 ===================================================================
 Функция для переопределения стандартного print()
 фактически предназначен для использования в t_QDroid
 все функции должны быть завязаны на функциональности объекта t_BaseBot
 ===================================================================
 */
//===============================================================================
// переопределение для функции print(строка)
static QScriptValue qdroid_print_function(QScriptContext *context, QScriptEngine *engine)
	{
         QString result;
         for (int i = 0; i < context->argumentCount(); ++i) {
             if (i > 0)
                 result.append(" ");
             result.append(context->argument(i).toString());
         };

         QScriptValue calleeData = context->callee().data();
         t_BaseBot *BaseBot = qobject_cast<t_BaseBot*>(calleeData.toQObject());
         BaseBot->send_std_out(result);

         return engine->undefinedValue();
     }

// определим функцию exit(кодВозврата)
static QScriptValue qdroid_exit_function(QScriptContext *context, QScriptEngine *engine)
	{
         int result=0;
        // for (int i = 0; i < context->argumentCount(); ++i) {
        //     if (i > 0)
        ////         result=context->argument(0).toInteger();
        //     result.append(context->argument(i).toString());
        // }

         //QScriptValue calleeData = context->callee().data();
         //t_BaseBot *BaseBot = qobject_cast<t_BaseBot*>(calleeData.toQObject());
         //BaseBot->send_std_out(result);
	QApplication::quit();

         return engine->undefinedValue();
     }

/*
   определение для функции new_t_BaseBot(ИмяОбъекта)
   временная мера до того как будет создан t_ObjectRegistry
   который будет заниматься учетом новых типов объектов
   и предоставлять HiveQueen информацию о том что можно породить
   непосредственно порождением будет заниматься HiveQueen,
   т.к. ObjectRegistry не знает скриптовом движке и т.п.
*/

//===============================================================================
// определение для функции alert(строка)
//+2010.07.07
static QScriptValue qdroid_alert_function(QScriptContext *context, QScriptEngine *engine)
        {
         QString result;
         for (int i = 0; i < context->argumentCount(); ++i)
             {
                 if (i > 0)
                     result.append(" ");
                 result.append(context->argument(i).toString());
             };

         QScriptValue calleeData = context->callee().data();
         t_BaseBot *BaseBot = qobject_cast<t_BaseBot*>(calleeData.toQObject());
         BaseBot->msgbox_warning("[alert]",result);

         return engine->undefinedValue();
     }

//===============================================================================
// определение для функции alert(строка)
//+2010.11.02
static QScriptValue qdroid_LoadQDroidLibrary_function_loc(QScriptContext *context, QScriptEngine *engine)
        {

            return qdroid_LoadQDroidLibrary_function(context, engine);

        }
//===============================================================================
// определение для функции confirm(строка)
//+2010.07.07
static QScriptValue qdroid_confirm_function(QScriptContext *context, QScriptEngine *engine)
        {
         QString result;
         for (int i = 0; i < context->argumentCount(); ++i)
             {
                 if (i > 0)
                     result.append(" ");
                 result.append(context->argument(i).toString());
             };

         QScriptValue calleeData = context->callee().data();
         t_BaseBot *BaseBot = qobject_cast<t_BaseBot*>(calleeData.toQObject());

         int rez=BaseBot->msgbox_question("[confirm]",result,9);//1=ok, 8=cancel

         QScriptValue rezBool;
         if (rez==1) {rezBool = QScriptValue(true);}
            else {rezBool = QScriptValue(false);}


         return rezBool;//engine->undefinedValue();
     }

//===============================================================================
// определение для функции confirm(строка)
//+2010.07.07
/*
static QScriptValue qdroid_confirm_function(QScriptContext *context, QScriptEngine *engine)
        {
         QString result;
         for (int i = 0; i < context->argumentCount(); ++i)
             {
                 if (i > 0)
                     result.append(" ");
                 result.append(context->argument(i).toString());
             };

         QScriptValue calleeData = context->callee().data();
         t_BaseBot *BaseBot = qobject_cast<t_BaseBot*>(calleeData.toQObject());

         int rez=BaseBot->msgbox_question("[confirm]",result,9);//1=ok, 8=cancel

         QScriptValue rezBool;
         if (rez==1) {rezBool = QScriptValue(true);}
            else {rezBool = QScriptValue(false);}


         return rezBool;//engine->undefinedValue();
     }
//*/
//===============================================================================
// определение для функции prompt(строка)
//+2010.07.07
static QScriptValue qdroid_prompt_function(QScriptContext *context, QScriptEngine *engine)
        {
         QString result="", initValue="";
         //for (int i = 0; i < context->argumentCount(); ++i)
         //    {
         //        if (i > 0)
         //            result.append(" ");
         //        result.append(context->argument(i).toString());
         //    };
         if (context->argumentCount()>0) result.append(context->argument(0).toString());
         if (context->argumentCount()>1) initValue.append(context->argument(1).toString());

         QScriptValue calleeData = context->callee().data();
         t_BaseBot *BaseBot = qobject_cast<t_BaseBot*>(calleeData.toQObject());

         QString rez=BaseBot->inputdialog_get_text("[prompt]", result, initValue);//1=ok, 8=cancel

         QScriptValue rezBool=QScriptValue(rez);

         return rezBool;//engine->undefinedValue();
     }

//===============================================================================
// переопределение для функции isValueDefined(имяПеременной)
//+2010.07.07
//TODO: НЕ РАБОТАЕТ... пока... потом разберусь...
static QScriptValue qdroid_isValueDefined_function(QScriptContext *context, QScriptEngine *engine)
        {
         QString result;
         for (int i = 0; i < context->argumentCount(); ++i)
             {
                 if (i > 0)
                     result.append(" ");
                 result.append(context->argument(i).toString());
             };

         QScriptValue calleeData = context->callee().data();
         t_BaseBot *BaseBot = qobject_cast<t_BaseBot*>(calleeData.toQObject());

         //поищем это свойсво в вызывающем объекте, в this и в GlobalObject
         //полагаю, этого достаточно
         bool rez1 = context->activationObject().property(result).isValid();
         bool rez2 = context->thisObject().property(result).isValid();
         bool rez3 = engine->globalObject().property(result).isValid();

         QScriptValue retRez=QScriptValue( rez1 || rez2  || rez3 );
         return retRez;//engine->undefinedValue();
     }



//===============================================================================
/*
	new_t_BaseBot (ObjectVarName)
*/
static QScriptValue qdroid_new_t_BaseBot_function(QScriptContext *QSContext, QScriptEngine *QSEngine)
	{
/* basebot - единственный!
		QString name;
		name.clear();
		name.append(QSContext->argument(0).toString()); //первый параметр - это имя объекта который надо создать

		//qDebug() << "qdroid_new_t_BaseBot_function():[0051]: name=" << name;

		QScriptValue ScriptObjectValue = QSEngine->newQObject( new t_BaseBot(QSEngine) );
		QSEngine->globalObject().setProperty(name, ScriptObjectValue);

		return QSEngine->undefinedValue();
*/
	}


//проба конструктора что бы можно было создавать переменные в QScript просто указывая их тип
static QScriptValue qdroid_t_BaseBot_constructor(QScriptContext *QSContext, QScriptEngine *QSEngine)
	{
/* basebot - единственный!

		//t_BaseBot BaseBot;
		QScriptValue qsBaseBot;
		qsBaseBot=QSEngine->newQObject(new t_BaseBot()); //
		//qsBaseBot=QSEngine->toScriptValue(BaseBot);
		return qsBaseBot;
*/
	}


static QScriptValue qdroid_t_BaseBot_toScriptValue(QScriptEngine *engine, t_BaseBot* const &in)
{ return engine->newQObject(in); }

static void qdroid_t_BaseBot_fromScriptValue(const QScriptValue &object, t_BaseBot* &out)
{ out = qobject_cast<t_BaseBot*>(object.toQObject()); }


//====================================================================
// various std classes
//QWidget
static QScriptValue qdroid_QWidget_constructor(QScriptContext *QSContext, QScriptEngine *QSEngine)
	{
		//t_BaseBot BaseBot;
		QScriptValue qsObject;
		qsObject=QSEngine->newQObject(new QWidget()); //
		return qsObject;
	}

//QGridLayout

//======================================================================
// функция которая собственно и переопредляет print() в указанном движке QTScript
// и ряд других
// пусть все переопределнные функции привязываются к t_BaseBot.
//======================================================================
static int define__qdroid_qtscript_functions(QScriptEngine *_QSEngine,t_BaseBot *_BaseBot, t_QDLibManager *_QDLibManager)
	{

		//--[print()]-------------------------------------------------
		// print() redefenition
			QScriptValue fun = _QSEngine->newFunction(qdroid_print_function,1);
			fun.setData(_QSEngine->newQObject(_BaseBot));
			//fun.setData(ScriptObjectValue1);
			_QSEngine->globalObject().setProperty("print", fun);

		//--[exit()]-------------------------------------------------
		// exit() defenition
			QScriptValue fun_exit = _QSEngine->newFunction(qdroid_exit_function,0);
			fun_exit.setData(_QSEngine->newQObject(_BaseBot));
			//fun.setData(ScriptObjectValue1);
			_QSEngine->globalObject().setProperty("exit", fun_exit);

		//--[loadlib_qd()]-------------------------------------------------
		// loadlib_qd() defenition
                        QScriptValue fun_loadlib_qd = _QSEngine->newFunction(qdroid_LoadQDroidLibrary_function_loc,1);
			fun_loadlib_qd.setData(_QSEngine->newQObject(_QDLibManager));
			_QSEngine->globalObject().setProperty("loadlib_qd", fun_loadlib_qd);

                //+2010.07.07
                //--[bool=isValueDefined()]-------------------------------------------------
                // isValueDefined() defenition
                        QScriptValue fun_isValueDefined_qd = _QSEngine->newFunction(qdroid_isValueDefined_function,1);
                        fun_isValueDefined_qd.setData(_QSEngine->newQObject(_BaseBot));
                        _QSEngine->globalObject().setProperty("isValueDefined", fun_isValueDefined_qd);

                //+2010.07.07
                //--[alert()]-------------------------------------------------
                // alert() defenition
                        QScriptValue fun_alert_qd = _QSEngine->newFunction(qdroid_alert_function,1);
                        fun_alert_qd.setData(_QSEngine->newQObject(_BaseBot));
                        _QSEngine->globalObject().setProperty("alert", fun_alert_qd);

                //+2010.07.07
/*
    confirm -ok
    alert - ok
    prompt -ok
    setInterval
    setTimeout
//    typeof
//instanceOf ??
*/
                //--[confirm()]-------------------------------------------------
                // confirm() defenition
                        QScriptValue fun_confirm_qd = _QSEngine->newFunction(qdroid_confirm_function,1);
                        fun_confirm_qd.setData(_QSEngine->newQObject(_BaseBot));
                        _QSEngine->globalObject().setProperty("confirm", fun_confirm_qd);

                //--[prompt()]-------------------------------------------------
                // prompt() defenition
                        QScriptValue fun_prompt_qd = _QSEngine->newFunction(qdroid_prompt_function,1);
                        fun_prompt_qd.setData(_QSEngine->newQObject(_BaseBot));
                        _QSEngine->globalObject().setProperty("prompt", fun_prompt_qd);


/*
basebot - единственный! копий не надо
		//--[t_BaseBot]-------------------------------------------------
				// new_t_BaseBot() defenition
					QScriptValue fun2 = _QSEngine->newFunction(qdroid_new_t_BaseBot_function);
					//fun.setData(_QSEngine->newQObject(_BaseBot));
					_QSEngine->globalObject().setProperty("new_t_BaseBot", fun2);

				// t_BaseBot type registration
					//Q_DECLARE_METATYPE(t_BaseBot);
					qScriptRegisterMetaType(_QSEngine, qdroid_t_BaseBot_toScriptValue, qdroid_t_BaseBot_fromScriptValue);

				// t_BaseBot constructor defenition
				//for object creation like: "var BBot3=new t_BaseBot;"
					QScriptValue fun2_constr = _QSEngine->newFunction(qdroid_t_BaseBot_constructor);
					//fun.setData(_QSEngine->newQObject(_BaseBot));
					_QSEngine->globalObject().setProperty("t_BaseBot", fun2_constr);
*/


			//--[t_FileList]-------------------------------------------------
				// спец. настройки для QtScript (v 2008.11.25)
				// Шаг 7 из 8
				qScriptRegisterMetaType(_QSEngine, qdroid_t_FileList_toScriptValue, qdroid_t_FileList_fromScriptValue);

				// спец. настройки для QtScript (v 2008.11.25)
				// Шаг 8 из 8
				//- определение конструктора в контексте скрипта
				/// t_FileList NEW constructor defenition
				QScriptValue t_FileList_qtsconstr = _QSEngine->newFunction(qdroid_t_FileList_constructor);
				_QSEngine->globalObject().setProperty("t_FileList", t_FileList_qtsconstr);


			//--[t_FileListElement]-------------------------------------------------
				// как надо!
				// t_FileListElement TYPE defenition
					qScriptRegisterMetaType(_QSEngine, qdroid_t_FileListElement_toScriptValue, qdroid_t_FileListElement_fromScriptValue);
					//qScriptRegisterMetaType(_QSEngine, qdroid_t_FileListElementO_toScriptValue, qdroid_t_FileListElementO_fromScriptValue);
				// t_FileListElement NEW constructor defenition
					QScriptValue fun4_constr = _QSEngine->newFunction(qdroid_t_FileListElement_constructor);
					_QSEngine->globalObject().setProperty("t_FileListElement", fun4_constr);


			//--[t_TreeWidget]-------------------------------------------------
				// t_TreeWidget TYPE defenition
					qScriptRegisterMetaType(_QSEngine, qdroid_t_TreeWidget_toScriptValue, qdroid_t_TreeWidget_fromScriptValue);
				// t_TreeWidget NEW constructor defenition
					QScriptValue t_TreeWidget_constr_func = _QSEngine->newFunction(qdroid_t_TreeWidget_constructor);
					_QSEngine->globalObject().setProperty("t_TreeWidget", t_TreeWidget_constr_func);

			//--[t_TreeWidgetItem]-------------------------------------------------
				// t_TreeWidgetItem TYPE defenition
					qScriptRegisterMetaType(_QSEngine, qdroid_t_TreeWidgetItem_toScriptValue, qdroid_t_TreeWidgetItem_fromScriptValue);

				// спец. настройки для QtScript (v 2008.11.25)
				// t_TreeWidgetItem NEW constructor defenition
					QScriptValue t_TreeWidgetItem_constr_func = _QSEngine->newFunction(qdroid_t_TreeWidgetItem_constructor);
					_QSEngine->globalObject().setProperty("t_TreeWidgetItem", t_TreeWidgetItem_constr_func);

			//--[t_FileBot]-------------------------------------------------
					qScriptRegisterMetaType(_QSEngine, qdroid_t_FileBot_toScriptValue, qdroid_t_FileBot_fromScriptValue);
					QScriptValue t_FileBot_constr_func = _QSEngine->newFunction(qdroid_t_FileBot_constructor);
					_QSEngine->globalObject().setProperty("t_FileBot", t_FileBot_constr_func);



			//--[ various ]-------------------------------------------------
				// спец. настройки для QtScript (v 2008.11.25)
				// QWidget NEW constructor defenition
					QScriptValue QWidget_constr_func = _QSEngine->newFunction(qdroid_QWidget_constructor);
					_QSEngine->globalObject().setProperty("QWidget", QWidget_constr_func);

				// QPushButton declaration and constructor
					qScriptRegisterMetaType(_QSEngine, qdroid_QPushButton_toScriptValue, qdroid_QPushButton_fromScriptValue);
					QScriptValue QPushButton_constr_func = _QSEngine->newFunction(qdroid_QPushButton_constructor);
					_QSEngine->globalObject().setProperty("QPushButton", QPushButton_constr_func);


		return 0;
	}

//real defenition



#endif /* GLOBAL_FUNCTIONS_H_ */
